// 《围棋》作者版权所有。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package syntax

import (
	"fmt"
	"io"
	"strconv"
	"strings"
)

const debug = false
const trace = false

type parser struct {
	file  *PosBase
	errh  ErrorHandler
	mode  Mode
	pragh PragmaHandler
	scanner

	base   *PosBase // 当前位置基
	first  error    // 遇到的第一个错误
	errcnt int      // 遇到的错误数
	pragma Pragma   // pragmas 

	fnest  int    // 函数嵌套级别（用于错误处理）
	xnest  int    // 表达式嵌套级别（用于complit歧义解决）
	indent []byte // 跟踪支持
}

func (p *parser) init(file *PosBase, r io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) {
	p.file = file
	p.errh = errh
	p.mode = mode
	p.pragh = pragh
	p.scanner.init(
		r,
		// 错误和指令处理程序用于扫描仪。
		// 由于传递给
		// 处理程序的（行、列）位置始终位于当前读取的
		// 位置或之后，因此可以安全地使用最新的位置
		// 基来计算相应的Pos值。
		func(line, col uint, msg string) {
			if msg[0] != '/' {
				p.errorAt(p.posAt(line, col), msg)
				return
			}

			// 否则它必须是一个包含行或go:指令的注释。
			// 
			// *行*/指令可以在行中的任何位置。
			text := commentText(msg)
			if (col == colbase || msg[1] == '*') && strings.HasPrefix(text, "line ") {
				var pos Pos // 紧跟在注释后面的位置
				if msg[1] == '/' {
					// 行注释（换行是注释的一部分）
					pos = MakePos(p.file, line+1, colbase)
				} else {
					// 常规注释
					// （如果注释跨越多行，它不是
					// 一个有效的行指令，将被updateBase丢弃
					// 指令
					pos = MakePos(p.file, line, col+uint(len(msg)))
				}
				return
			}

			if pragh != nil && strings.HasPrefix(text, "go:") {
				p.pragma = pragh(p.posAt(line, col+2), p.scanner.blank, text, p.pragma) // /+2跳过
			}
		},
		directives,
	)

	p.base = file
	p.first = nil
	p.errcnt = 0
	p.pragma = nil

	p.fnest = 0
	p.xnest = 0
	p.indent = nil
}

func (p *parser) allowGenerics() bool { return p.mode&AllowGenerics != 0 }

// takePragma返回当前解析的pragmas 
// 并将其从解析器状态中清除。
func (p *parser) takePragma() Pragma {
	prag := p.pragma
	p.pragma = nil
	return prag
}

// 在语句末尾调用clearPragma，或
// 其他不接受pragma的Go表单。
// 它将pragma发送回pragma处理程序
// 以报告为未使用。
func (p *parser) clearPragma() {
	if p.pragma != nil {
		p.pragh(p.pos(), p.scanner.blank, "", p.pragma)
		p.pragma = nil
	}
}

// updateBase将当前位置基设置为位置处的新行基。
// 基的文件名、行和列值从文本
// 中提取，该文本位于（tline，tcol）（仅用于错误消息）。
func (p *parser) updateBase(pos Pos, tline, tcol uint, text string) {
	i, n, ok := trailingDigits(text)
	if i == 0 {
		return // ignore（非行指令）
	}
	// i>0 

	if !ok {
		// text有后缀：xxx但xxx不是数字
		p.errorAt(p.posAt(tline, tcol+i), "invalid line number: "+text[i:])
		return
	}

	var line, col uint
	i2, n2, ok2 := trailingDigits(text[:i-1])
	if ok2 {
		// line filename:line:col 
		i, i2 = i2, i
		line, col = n2, n
		if col == 0 || col > PosMax {
			p.errorAt(p.posAt(tline, tcol+i2), "invalid column number: "+text[i2:])
			return
		}
		text = text[:i2-1] // lop off:col 
	} else {
		// line filename:line 
		line = n
	}

	if line == 0 || line > PosMax {
		p.errorAt(p.posAt(tline, tcol+i), "invalid line number: "+text[i:])
		return
	}

	// 空文件名意味着使用以前的文件名。
	filename := text[:i-1] // lop off:line“
	trimmed := false
	if filename == "" && ok2 {
		filename = p.base.Filename()
		trimmed = p.base.Trimmed()
	}

	p.base = NewLineBase(pos, filename, trimmed, line, col)
}

func commentText(s string) string {
	if s[:2] == "/*" {
		return s[2 : len(s)-2] // /lop off/*和*/
	}

	// line comment（不包括换行）
	// （在Windows上，行注释可能以\r\n结尾）
	i := len(s)
	if s[i-1] == '\r' {
		i--
	}
}

func trailingDigits(text string) (uint, uint, bool) {
	i := strings.LastIndex(text, ":") // 从右边看（Windows文件名可能包含“：”）
	if i < 0 {
		return 0, 0, false // 否：“
	}
	// i>=0 
	n, err := strconv.ParseUint(text[i+1:], 10, 0)
	return uint(i + 1), uint(n), err == nil
}

func (p *parser) got(tok token) bool {
	if p.tok == tok {
		p.next()
		return true
	}
	return false
}

func (p *parser) want(tok token) {
	if !p.got(tok) {
		p.syntaxError("expecting " + tokstring(tok))
		p.advance()
	}
}

// gotAssign类似于got（_Assign），但它也接受“：=”
// （并报告一个错误）以更好地恢复解析器错误。
func (p *parser) gotAssign() bool {
	switch p.tok {
	case _Define:
		p.syntaxError("expecting =")
		fallthrough
	case _Assign:
		p.next()
		return true
	}
	return false
}

// ---------------------------------------------------------------
// 错误处理

// posAt返回（行、列）的Pos值和当前位置基数。
func (p *parser) posAt(line, col uint) Pos {
	return MakePos(p.base, line, col)
}

// 错误报告给定位置的错误。
func (p *parser) errorAt(pos Pos, msg string) {
	err := Error{pos, msg}
	if p.first == nil {
		p.first = err
	}
	p.errcnt++
	if p.errh == nil {
		panic(p.first)
	}
	p.errh(err)
}

// syntaxErrorAt报告给定位置的语法错误。
func (p *parser) syntaxErrorAt(pos Pos, msg string) {
	if trace {
		p.print("syntax error: " + msg)
	}

	if p.tok == _EOF && p.first != nil {
		return // 避免无意义的后续错误
	}

	// 根据需要添加标点符号等信息
	switch {
	case msg == "":
		// 无需执行
	case strings.HasPrefix(msg, "in "), strings.HasPrefix(msg, "at "), strings.HasPrefix(msg, "after "):
		msg = " " + msg
	case strings.HasPrefix(msg, "expecting "):
		msg = ", " + msg
	default:
		// 纯错误-我们不关心当前标记
		p.errorAt(pos, "syntax error: "+msg)
		return
	}

	// 确定标记字符串
	var tok string
	switch p.tok {
	case _Name, _Semi:
		tok = p.lit
	case _Literal:
		tok = "literal " + p.lit
	case _Operator:
		tok = p.op.String()
	case _AssignOp:
		tok = p.op.String() + "="
	case _IncOp:
		tok = p.op.String()
		tok += tok
	default:
		tok = tokstring(p.tok)
	}

	p.errorAt(pos, "syntax error: unexpected "+tok+msg)
}

// tokstring返回所选标点符号的英文单词
// 以获取更可读的错误信息信息。使用tokstring（而不是tok.String（））
// 发送面向用户的（错误）消息；使用tok。用于调试
// 输出的字符串（）。
func tokstring(tok token) string {
	switch tok {
	case _Comma:
		return "comma"
	case _Semi:
		return "semicolon or newline"
	}
	return tok.String()
}

// 使用当前令牌位置的便利方法。
func (p *parser) pos() Pos               { return p.posAt(p.line, p.col) }
func (p *parser) error(msg string)       { p.errorAt(p.pos(), msg) }
func (p *parser) syntaxError(msg string) { p.syntaxErrorAt(p.pos(), msg) }

// 停止集包含开始语句的关键字。
// 在语法错误的情况下，它们是很好的同步点，并且（通常）不应该被跳过。
const stopset uint64 = 1<<_Break |
	1<<_Const |
	1<<_Continue |
	1<<_Defer |
	1<<_Fallthrough |
	1<<_For |
	1<<_Go |
	1<<_Goto |
	1<<_If |
	1<<_Return |
	1<<_Select |
	1<<_Switch |
	1<<_Type |
	1<<_Var

// Advance使用代币，直到找到stopset或followlist的代币。
// 只有在函数内部（p.fnest>0）才会考虑停止集。
// followlist是可以跟随生产的有效令牌列表；
// 如果为空，则只消耗一个（非EOF）令牌以确保进度。
func (p *parser) advance(followlist ...token) {
	if trace {
		p.print(fmt.Sprintf("advance %s", followlist))
	}

	// compute follow set 
	// （非速度关键型，仅在错误情况下调用advance）
	var followset uint64 = 1 << _EOF // 不要跳过EOF 
	if len(followlist) > 0 {
		if p.fnest > 0 {
			followset |= stopset
		}
		for _, tok := range followlist {
			followset |= 1 << tok
		}
	}

	for !contains(followset, p.tok) {
		if trace {
			p.print("skip " + p.tok.String())
		}
		p.next()
		if len(followlist) == 0 {
			break
		}
	}

	if trace {
		p.print("next " + p.tok.String())
	}
}

// 用法：延迟p.trace（msg）（）
func (p *parser) trace(msg string) func() {
	p.print(msg + " (")
	const tab = ". "
	p.indent = append(p.indent, tab...)
	return func() {
		p.indent = p.indent[:len(p.indent)-len(tab)]
		if x := recover(); x != nil {
			panic(x) // skip print_trace 
		}
		p.print(")")
	}
}

func (p *parser) print(msg string) {
	fmt.Printf("%5d: %s%s\n", p.line, p.indent, msg)
}

// ----------------------------------------------------------------------------------------
// 包文件
// 
// 解析方法根据需要使用匹配的Go产品进行注释。
// 注释仅供参考，因为单步语法
// 规则可能包含在多个解析方法中，反之亦然。
// 
// 不包括返回切片的方法，名为xOrNil的解析方法可能返回
// nil；所有其他节点都应返回有效的非nil节点。

// SourceFile=PackageClause“{ImportDecl”；“}{TopLevelDecl”；“}。
func (p *parser) fileOrNil() *File {
	if trace {
		defer p.trace("file")()
	}

	f := new(File)
	f.pos = p.pos()

	// PackageClause 
	if !p.got(_Package) {
		p.syntaxError("package statement must be first")
		return nil
	}
	f.Pragma = p.takePragma()
	f.PkgName = p.name()
	p.want(_Semi)

	// 如果package子句有错误，请不要麻烦继续
	if p.first != nil {
		return nil
	}

	for p.got(_Import) {
		f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
		p.want(_Semi)
	}

	// /{TopLevelDecl“}
	for p.tok != _EOF {
		switch p.tok {
		case _Const:
			p.next()
			f.DeclList = p.appendGroup(f.DeclList, p.constDecl)

		case _Type:
			p.next()
			f.DeclList = p.appendGroup(f.DeclList, p.typeDecl)

		case _Var:
			p.next()
			f.DeclList = p.appendGroup(f.DeclList, p.varDecl)

		case _Func:
			p.next()
			if d := p.funcDeclOrNil(); d != nil {
				f.DeclList = append(f.DeclList, d)
			}

		default:
			if p.tok == _Lbrace && len(f.DeclList) > 0 && isEmptyFuncDecl(f.DeclList[len(f.DeclList)-1]) {
				// 打开{下一行的函数声明
				p.syntaxError("unexpected semicolon or newline before {")
			} else {
				p.syntaxError("non-declaration statement outside function body")
			}
			p.advance(_Const, _Type, _Var, _Func)
			continue
		}

		// 在前进到下一个标记之前重置p.pragma（使用“；”）
		// 因为之前的注释可能会为下一个函数decl设置pragmas。
		p.clearPragma()

		if p.tok != _EOF && !p.got(_Semi) {
			p.syntaxError("after top level declaration")
			p.advance(_Const, _Type, _Var, _Func)
		}
	}
	// p.tok==_eofabcdefg

	p.clearPragma()
	f.EOF = p.pos()

	return f
}

func isEmptyFuncDecl(dcl Decl) bool {
	f, ok := dcl.(*FuncDecl)
	return ok && f.Body == nil
}

// 声明

// list解析一个可能为空的、sep分隔的元素列表，可选的是
// 后跟sep，并通过close（或EOF）关闭。sep必须是_逗号
// /或_Semi之一，close必须是_Rparen、_Rbrace或_Rbrack之一。
// 
// 对于每个列表元素，调用f。具体来说，除非我们接近
// /（或EOF），否则f至少被调用一次。f返回true后，不再接受更多的列表
// 元素。列表返回结束标记的位置。
// 
// list=[f{sep f}[sep]]关闭。
// 
func (p *parser) list(sep, close token, f func() bool) Pos {
	if debug && (sep != _Comma && sep != _Semi || close != _Rparen && close != _Rbrace && close != _Rbrack) {
		panic("invalid sep or close argument for list")
	}

	done := false
	for p.tok != _EOF && p.tok != close && !done {
		done = f()
		// sep在关闭前是可选的
		if !p.got(sep) && p.tok != close {
			p.syntaxError(fmt.Sprintf("expecting %s or %s", tokstring(sep), tokstring(close)))
			p.advance(_Rparen, _Rbrack, _Rbrace)
			if p.tok != close {
				// 位置可能会更好，但我们有一个错误，所以我们不在乎
				return p.pos()
			}
		}
	}

	pos := p.pos()
	p.want(close)
	return pos
}

// appendGroup（f）=f |“（“{f”；”）")" . 
func (p *parser) appendGroup(list []Decl, f func(*Group) Decl) []Decl {
	if p.tok == _Lparen {
		g := new(Group)
		p.clearPragma()
		p.next() // 必须消费”之前是可选的（“在调用clearPragma！
		p.list(_Semi, _Rparen, func() bool {
			if x := f(g); x != nil {
				list = append(list, x)
			}
			return false
		})
	} else {
		if x := f(nil); x != nil {
			list = append(list, x)
		}
	}
	return list
}

// ImportSpec=[”之后）PackageName]导入路径。
// ImportPath=字符串点亮。
func (p *parser) importDecl(group *Group) Decl {
	if trace {
		defer p.trace("importDecl")()
	}

	d := new(ImportDecl)
	d.pos = p.pos()
	d.Group = group
	d.Pragma = p.takePragma()

	switch p.tok {
	case _Name:
		d.LocalPkgName = p.name()
	case _Dot:
		d.LocalPkgName = NewName(p.pos(), ".")
		p.next()
	}
	d.Path = p.oliteral()
	if d.Path == nil {
		p.syntaxError("missing import path")
		p.advance(_Semi, _Rparen)
		return d
	}
	if !d.Path.Bad && d.Path.Kind != StringLit {
		p.syntaxError("import path must be a string")
		d.Path.Bad = true
	}
	// d.Path。坏的| | d.路。Kind==StringLit 

	return d
}

// ConstSpec=IdentifierList[[Type]“=”ExpressionList]。
func (p *parser) constDecl(group *Group) Decl {
	if trace {
		defer p.trace("constDecl")()
	}

	d := new(ConstDecl)
	d.pos = p.pos()
	d.Group = group
	d.Pragma = p.takePragma()

	d.NameList = p.nameList(p.name())
	if p.tok != _EOF && p.tok != _Semi && p.tok != _Rparen {
		d.Type = p.typeOrNil()
		if p.gotAssign() {
			d.Values = p.exprList()
		}
	}

	return d
}

// TypeSpec=标识符[TypeParams][“=”]类型。
func (p *parser) typeDecl(group *Group) Decl {
	if trace {
		defer p.trace("typeDecl")()
	}

	d := new(TypeDecl)
	d.pos = p.pos()
	d.Group = group
	d.Pragma = p.takePragma()

	d.Name = p.name()
	if p.allowGenerics() && p.tok == _Lbrack {
		// d.Name“[”…
		// 数组/切片类型或类型参数列表
		pos := p.pos()
		p.next()
		switch p.tok {
		case _Name:
			// 我们可能有一个数组类型或类型参数列表。
			// 在这两种情况下，我们都需要一个表达式x（可能是一个名称，或者更复杂的表达式）我们可以进一步分析。
			// 
			// 类型参数列表可能有一个以“[”开头的
			// 类型绑定，如：P[]E。在这种情况下，简单地解析
			// 表达式将导致错误：P[]无效。
			// 但由于索引或切片表达式从来都不是常量
			// 因此数组长度表达式无效，如果我们看到一个
			// “[”在一个名称后面，它必须是数组
			// 或切片约束的开始。只有当我们没有看到“[”时我们需要解析一个完整的表达式吗。
			var x Expr = p.name()
			if p.tok != _Lbrack {
				// 若要解析以名称开头的表达式，请展开
				// 我们将通过将名称
				// 传递给解析器获得的调用序列。expr，并将名称传递给解析器。pexpr。
				p.xnest++
				x = p.binaryExpr(p.pexpr(x, false), 0)
				p.xnest--
			}

			// 分析案例
			var pname *Name // pname！=nil表示pname是类型参数名
			var ptype Expr  // ptype！=nil表示ptype是类型参数类型；pname！=nil在本例中
			switch t := x.(type) {
			case *Name:
				// 除非我们看到“]”，否则我们处于类型参数列表的开头。
				if p.tok != _Rbrack {
					// d.Name“[”Name…
					pname = t
					// 没有p类型
				}
			case *Operation:
				// 如果我们有一个形式为Name*T的表达式，并且T是一个（可能是带括号的
				// 类型文字，或者下一个标记是一个逗号，那么在类型参数列表的开头，我们就是
				// d.Name”[“Name”*”T.Y 
				if name, _ := t.X.(*Name); name != nil {
					if t.Op == Mul && (isTypeLit(t.Y) || p.tok == _Comma) {
						t.X, t.Y = t.Y, nil // 将t转换为一元*t.Y 
						pname = name
						ptype = t
					}
				}
			case *CallExpr:
				// 如果我们有一个形式名称（t）的表达式，并且t是一个（可能是带括号的
				// 类型文字，或者下一个标记是逗号，那么在类型参数列表的开头就是
				// 了。
				if name, _ := t.Fun.(*Name); name != nil {
					if len(t.ArgList) == 1 && !t.HasDots && (isTypeLit(t.ArgList[0]) || p.tok == _Comma) {
						// d.Name“[“Name”（“t.ArgList[0]”）
						// d.Name“[“Name”（“t.ArgList[0]”）”，“
						pname = name
						ptype = t.ArgList[0]
					}
				}
			}

			if pname != nil {
				// d.Name”[“pname…
				// d.Name”[“pname”ptype…
				// d.Name“[“pname ptype”，“…
				d.TParamList = p.paramList(pname, ptype, _Rbrack, true)
				d.Alias = p.gotAssign()
				d.Type = p.typeOrNil()
			} else {
				// d.Name”[“x…
				d.Type = p.arrayType(pos, x)
			}
		case _Rbrack:
			// d.Name”[“”]。。。ABCFDG 
			p.next()
			d.Type = p.sliceType(pos)
		default:
			d.Type = p.arrayType(pos, nil)
		}
	} else {
		d.Alias = p.gotAssign()
		d.Type = p.typeOrNil()
	}

	if d.Type == nil {
		d.Type = p.badExpr()
		p.syntaxError("in type declaration")
		p.advance(_Semi, _Rparen)
	}

	return d
}

func isTypeLit(x Expr) bool {
	switch x := x.(type) {
	case *ArrayType, *StructType, *FuncType, *InterfaceType, *SliceType, *MapType, *ChanType:
		return true
	case *Operation:
		return x.Op == Mul && x.Y == nil && isTypeLit(x.X)
	case *ParenExpr:
		return isTypeLit(x.X)
	}
	return false
}

func (p *parser) varDecl(group *Group) Decl {
	if trace {
		defer p.trace("varDecl")()
	}

	d := new(VarDecl)
	d.pos = p.pos()
	d.Group = group
	d.Pragma = p.takePragma()

	d.NameList = p.nameList(p.name())
	if p.gotAssign() {
		d.Values = p.exprList()
	} else {
		d.Type = p.type_()
		if p.gotAssign() {
			d.Values = p.exprList()
		}
	}

	return d
}

// FunctionDecl=“func”FunctionName[TypeParams]（函数|签名）。
// 函数名=标识符。
// 函数=签名函数体。
// MethodDecl=“func”接收方方法名（函数|签名）。
// 接收器=参数。
func (p *parser) funcDeclOrNil() *FuncDecl {
	if trace {
		defer p.trace("funcDecl")()
	}

	f := new(FuncDecl)
	f.pos = p.pos()
	f.Pragma = p.takePragma()

	if p.got(_Lparen) {
		rcvr := p.paramList(nil, nil, _Rparen, false)
		switch len(rcvr) {
		case 0:
			p.error("method has no receiver")
		default:
			p.error("method has multiple receivers")
			fallthrough
		case 1:
			f.Recv = rcvr[0]
		}
	}

	if p.tok != _Name {
		p.syntaxError("expecting name or (")
		p.advance(_Lbrace, _Semi)
		return nil
	}

	f.Name = p.name()

	context := ""
	if f.Recv != nil && p.mode&AllowMethodTypeParams == 0 {
		context = "method" // 不允许funcType中的（方法）类型参数
	}
	f.TParamList, f.Type = p.funcType(context)

	if p.tok == _Lbrace {
		f.Body = p.funcBody()
	}

	return f
}

func (p *parser) funcBody() *BlockStmt {
	p.fnest++
	errcnt := p.errcnt
	body := p.blockStmt("")
	p.fnest--

	// 不要检查函数
	// 中是否存在语法错误，因为这可能会导致虚假错误（例如，请参阅test/switch2.go）或
	// 可能由于语法树不完整而崩溃。
	if p.mode&CheckBranches != 0 && errcnt == p.errcnt {
		checkBranches(body, p.errh)
	}

	return body
}

// ---------------------------------------------------------------
// 表达式

func (p *parser) expr() Expr {
	if trace {
		defer p.trace("expr")()
	}

	return p.binaryExpr(nil, 0)
}

// 表达式=UnaryExpr |表达式二进制_op表达式。
func (p *parser) binaryExpr(x Expr, prec int) Expr {
	// 不跟踪binaryExpr-只会导致过度嵌套的跟踪输出

	if x == nil {
		x = p.unaryExpr()
	}
	for (p.tok == _Operator || p.tok == _Star) && p.prec > prec {
		t := new(Operation)
		t.pos = p.pos()
		t.Op = p.op
		tprec := p.prec
		p.next()
		t.X = x
		t.Y = p.binaryExpr(nil, tprec)
		x = t
	}
	return x
}

// UnaryExpr=PrimaryExpr | unary|op UnaryExpr。
func (p *parser) unaryExpr() Expr {
	if trace {
		defer p.trace("unaryExpr")()
	}

	switch p.tok {
	case _Operator, _Star:
		switch p.op {
		case Mul, Add, Sub, Not, Xor:
			x := new(Operation)
			x.pos = p.pos()
			x.Op = p.op
			p.next()
			x.X = p.unaryExpr()
			return x

		case And:
			x := new(Operation)
			x.pos = p.pos()
			x.Op = And
			p.next()
			// unaryExpr可能返回了一个带括号的复合文字
			// （请参阅操作数中的注释）-如果有任何
			x.X = unparen(p.unaryExpr())
			return x
		}

	case _Arrow:
		// receive op（<-x）或receive only channel（<-chan E）
		pos := p.pos()
		p.next()

		// 如果下一个标记是_chan，我们仍然不知道它是
		// /一个通道（<-chan int）还是一个receive op（<-chan int（ch））。
		// 我们只有在找到一元表达式的结尾时才知道。有两种情况：

		x := p.unaryExpr()

		// 
		// <-chan…=><-x是信道类型
		// /<-x=><-x是接收操作
		// 
		// 在第一种情况下，<-必须重新关联到
		// 已解析的通道类型：
		// 
		// （chan E）=>（<chan E）
		// -（chan<-E）=>（<-chan（<-E））

		if _, ok := x.(*ChanType); ok {
			// x是一个通道类型=>重新关联<-
			dir := SendOnly
			t := x
			for dir == SendOnly {
				c, ok := t.(*ChanType)
				if !ok {
					break
				}
				dir = c.Dir
				if dir == RecvOnly {
					// t是类型<-chan E，但<-chan E不允许
					p.syntaxError("unexpected <-, expecting chan")
					// 已经进步，不需要进步
				}
				c.Dir = RecvOnly
				t = c.Elem
			}
			if dir == SendOnly {
				// 频道目录是<-但频道元素E不是频道
				// （报告与type<-chan<-E相同的错误）
				p.syntaxError(fmt.Sprintf("unexpected %s, expecting chan", String(t)))
				// 已经进步，无需提前
			}
			return x
		}

		// x不是通道类型=>我们有一个接收操作
		o := new(Operation)
		o.pos = pos
		o.Op = Recv
		o.X = x
		return o
	}

	// TODO（mdempsky）：我们需要在这里设置参数，以便我们可以报告
	// 错误（x）：=true）。应该可以检测到
	// 并更有效地拒绝。
	return p.pexpr(nil, true)
}

// callStmt解析类似于调用的语句，这些语句前面可以加上'defer'和'go'。
func (p *parser) callStmt() *CallStmt {
	if trace {
		defer p.trace("callStmt")()
	}

	s := new(CallStmt)
	s.pos = p.pos()
	s.Tok = p.tok // /\u推迟或_Go
	p.next()

	x := p.pexpr(nil, p.tok == _Lparen) // /保留参数，以便我们可以在
	if t := unparen(x); t != x {
		p.errorAt(x.Pos(), fmt.Sprintf("expression in %s must not be parenthesized", s.Tok))
		// /下报告错误，已取得进展，无需提前
		x = t
	}

	cx, ok := x.(*CallExpr)
	if !ok {
		p.errorAt(x.Pos(), fmt.Sprintf("expression in %s must be function call", s.Tok))
		// /已取得进展，无需提前
		cx = new(CallExpr)
		cx.pos = x.Pos()
		cx.Fun = x // 假设缺少括号的常见错误（函数调用）
	}

	s.Call = cx
	return s
}

// 操作数=文字|操作数名称| MethodExpr |“（“表达式”）”。
// Literal=BasicLit | CompositeLit | FunctionLit。
// BasicLit=int_lit | float|u lit | imaginal|u lit |符文|字符串|。
// 操作数名称=标识符|限定。
func (p *parser) operand(keep_parens bool) Expr {
	if trace {
		defer p.trace("operand " + p.tok.String())()
	}

	switch p.tok {
	case _Name:
		return p.name()

	case _Literal:
		return p.oliteral()

	case _Lparen:
		pos := p.pos()
		p.next()
		p.xnest++
		x := p.expr()
		p.xnest--
		p.want(_Rparen)

		// 优化：仅在需要时记录（）的存在
		// 用于错误报告。在其他情况下不要麻烦；这是对记忆和时间的浪费。
		// 
		// 在复合
		// 文本T{}中，T的周围不允许有括号。如果下一个标记是{，假设x是
		// 复合文字类型T（它可能不是，{可能是
		// 块的左括号，但我们还不知道）.
		if p.tok == _Lbrace {
			keep_parens = true
		}

		// 在go/defer语句中，表达式
		// 周围也不允许使用括号。在这种情况下，操作数被称为
		// 并设置了keep_parens。
		if keep_parens {
			px := new(ParenExpr)
			px.pos = pos
			px.X = x
			x = px
		}
		return x

	case _Func:
		pos := p.pos()
		p.next()
		_, ftyp := p.funcType("function literal")
		if p.tok == _Lbrace {
			p.xnest++

			f := new(FuncLit)
			f.pos = pos
			f.Type = ftyp
			f.Body = p.funcBody()

			p.xnest--
			return f
		}
		return ftyp

	case _Lbrack, _Chan, _Map, _Struct, _Interface:
		return p.type_() // 其他类型

	default:
		x := p.badExpr()
		p.syntaxError("expecting expression")
		p.advance(_Rparen, _Rbrack, _Rbrace)
		return x
	}

	// 在语法上，复合文字是操作数。因为complit 
	// 类型可能是由pexpr 
	// （以及选择器表达式）处理的限定标识符，所以complit也会在那里解析
	// （仅从pexpr调用操作数）。
}

// PrimaryExpr=
// 操作数| 
// 转换| 
// PrimaryExpr选择器| 
// PrimaryExpr索引| 
// PrimaryExpr切片| 
// PrimaryExpr类型断言| 
// PrimaryExpr参数。
// 
// Selector=“”标识符。
// Index=“[“表达式”]”。
// Slice=“[”（[Expression]：“[Expression]）| 
// /（[Expression]：“Expression:“Expression:”Expression）
// /“]”。
// TypeAssertion=“”“（“类型”）”。
// Arguments=“（“[（ExpressionList | Type[”，“ExpressionList]）[”…][ "," ] ] ")" . 
func (p *parser) pexpr(x Expr, keep_parens bool) Expr {
	if trace {
		defer p.trace("pexpr")()
	}

	if x == nil {
		x = p.operand(keep_parens)
	}

loop:
	for {
		pos := p.pos()
		switch p.tok {
		case _Dot:
			p.next()
			switch p.tok {
			case _Name:
				// pexpr''sym 
				t := new(SelectorExpr)
				t.pos = pos
				t.X = x
				t.Sel = p.name()
				x = t

			case _Lparen:
				p.next()
				if p.got(_Type) {
					t := new(TypeSwitchGuard)
					// t.Lhs由解析器填写。simpleStmt 
					t.pos = pos
					t.X = x
					x = t
				} else {
					t := new(AssertExpr)
					t.pos = pos
					t.X = x
					t.Type = p.type_()
					x = t
				}
				p.want(_Rparen)

			default:
				p.syntaxError("expecting name or (")
				p.advance(_Semi, _Rparen)
			}

		case _Lbrack:
			p.next()

			if p.tok == _Rbrack {
				// 无效的空实例、切片或索引表达式；接受但抱怨
				p.syntaxError("expecting operand")
				p.next()
				break
			}

			var i Expr
			if p.tok != _Colon {
				if p.mode&AllowGenerics == 0 {
					p.xnest++
					i = p.expr()
					p.xnest--
					if p.got(_Rbrack) {
						t := new(IndexExpr)
						t.pos = pos
						t.X = x
						t.Index = i
						x = t
						break
					}
				} else {
					var comma bool
					i, comma = p.typeList()
					if comma || p.tok == _Rbrack {
						p.want(_Rbrack)
						t := new(IndexExpr)
						t.pos = pos
						t.X = x
						t.Index = i
						x = t
						break
					}
				}
			}

			// x[i:…
			// 为了获得更好的错误消息，不要在这里简单地使用p.want（_冒号）（问题#47704）。
			if !p.got(_Colon) {
				if p.mode&AllowGenerics == 0 {
					p.syntaxError("expecting : or ]")
					p.advance(_Colon, _Rbrack)
				} else {
					p.syntaxError("expecting comma, : or ]")
					p.advance(_Comma, _Colon, _Rbrack)
				}
			}
			p.xnest++
			t := new(SliceExpr)
			t.pos = pos
			t.X = x
			t.Index[0] = i
			if p.tok != _Colon && p.tok != _Rbrack {
				// x[i:j…
				t.Index[1] = p.expr()
			}
			if p.tok == _Colon {
				t.Full = true
				// x[i:j:…]
				if t.Index[1] == nil {
					p.error("middle index required in 3-index slice")
					t.Index[1] = p.badExpr()
				}
				p.next()
				if p.tok != _Rbrack {
					// x[i:j:k…
					t.Index[2] = p.expr()
				} else {
					p.error("final index required in 3-index slice")
					t.Index[2] = p.badExpr()
				}
			}
			p.xnest--
			p.want(_Rbrack)
			x = t

		case _Lparen:
			t := new(CallExpr)
			t.pos = pos
			p.next()
			t.Fun = x
			t.ArgList, t.HasDots = p.argList()
			x = t

		case _Lbrace:
			// 操作数可能返回了带括号的complit 
			// 键入；接受它，但如果我们有complit 
			t := unparen(x)
			// 请确定{'属于复合文字或块语句
			complit_ok := false
			switch t.(type) {
			case *Name, *SelectorExpr:
				if p.xnest >= 0 {
					// x可能是复合文字类型
					complit_ok = true
				}
			case *IndexExpr:
				if p.xnest >= 0 && !isValue(t) {
					// x可能是复合文字类型
					complit_ok = true
				}
			case *ArrayType, *SliceType, *StructType, *MapType:
				// x是复合文字类型
				complit_ok = true
			}
			if !complit_ok {
				break loop
			}
			if t != x {
				p.syntaxError("cannot parenthesize type in composite literal")
				// 已在进行，无需提前
			}
			n := p.complitexpr()
			n.Type = x
			x = n

		default:
			break loop
		}
	}

	return x
}

// isValue报告x在语法上是否必须是值（而不是类型）表示
func isValue(x Expr) bool {
	switch x := x.(type) {
	case *BasicLit, *CompositeLit, *FuncLit, *SliceExpr, *AssertExpr, *TypeSwitchGuard, *CallExpr:
		return true
	case *Operation:
		return x.Op != Mul || x.Y != nil // *T可以是类型
	case *ParenExpr:
		return isValue(x.X)
	case *IndexExpr:
		return isValue(x.X) || isValue(x.Index)
	}
	return false
}

// /Element=Expression | LiteralValue。
func (p *parser) bare_complitexpr() Expr {
	if trace {
		defer p.trace("bare_complitexpr")()
	}

	if p.tok == _Lbrace {
		// /'{'start_complit brated_keyval_list'}'
		return p.complitexpr()
	}

	return p.expr()
}

// /LiteralValue=“{”[ElementList[，“]]”字符集]。
func (p *parser) complitexpr() *CompositeLit {
	if trace {
		defer p.trace("complitexpr")()
	}

	x := new(CompositeLit)
	x.pos = p.pos()

	p.xnest++
	p.want(_Lbrace)
	x.Rbrace = p.list(_Comma, _Rbrace, func() bool {
		// value 
		e := p.bare_complitexpr()
		if p.tok == _Colon {
			// key'：'value 
			l := new(KeyValueExpr)
			l.pos = p.pos()
			p.next()
			l.Key = e
			l.Value = p.bare_complitexpr()
			e = l
			x.NKeys++
		}
		x.ElemList = append(x.ElemList, e)
		return false
	})
	p.xnest--

	return x
}

// ----------------------------------------------------------------------------------------
// Types 

func (p *parser) type_() Expr {
	if trace {
		defer p.trace("type_")()
	}

	typ := p.typeOrNil()
	if typ == nil {
		typ = p.badExpr()
		p.syntaxError("expecting type")
		p.advance(_Comma, _Colon, _Semi, _Rparen, _Rbrack, _Rbrace)
	}

	return typ
}

func newIndirect(pos Pos, typ Expr) Expr {
	o := new(Operation)
	o.pos = pos
	o.Op = Mul
	o.X = typ
	return o
}

// typeOrNil类似于类型u，但如果没有类型
// ，则返回零，而不是报告错误。
// 
// Type=TypeName | TypeLit |“（“Type”）”。
// TypeName=identifier | QualifiedIdent。
// TypeLit=ArrayType | StructType | PointerType | FunctionType | InterfaceType | 
// SliceType | MapType | Channel | U Type。
func (p *parser) typeOrNil() Expr {
	if trace {
		defer p.trace("typeOrNil")()
	}

	pos := p.pos()
	switch p.tok {
	case _Star:
		// pRTYPE 
		p.next()
		return newIndirect(pos, p.type_())

	case _Arrow:
		// fntype 
		p.next()
		p.want(_Chan)
		t := new(ChanType)
		t.pos = pos
		t.Dir = RecvOnly
		t.Elem = p.chanElem()
		return t

	case _Func:
		// fntype 
		p.next()
		_, t := p.funcType("function type")
		return t

	case _Lbrack:
		// /'['oexpr']'ntype 
		// /'['''u dotdot']]ntype 
		p.next()
		if p.got(_Rbrack) {
			return p.sliceType(pos)
		}
		return p.arrayType(pos, nil)

	case _Chan:
		// .\u Chan non recvchan 
		// /\u Chan“”中，不允许使用类型参数。
		p.next()
		t := new(ChanType)
		t.pos = pos
		if p.got(_Arrow) {
			t.Dir = SendOnly
		}
		t.Elem = p.chanElem()
		return t

	case _Map:
		p.next()
		p.want(_Lbrack)
		t := new(MapType)
		t.pos = pos
		t.Key = p.type_()
		p.want(_Rbrack)
		t.Value = p.type_()
		return t

	case _Struct:
		return p.structType()

	case _Interface:
		return p.interfaceType()

	case _Name:
		return p.qualifiedName(nil)

	case _Lparen:
		p.next()
		t := p.type_()
		p.want(_Rparen)
		return t
	}

	return nil
}

func (p *parser) typeInstance(typ Expr) Expr {
	if trace {
		defer p.trace("typeInstance")()
	}

	pos := p.pos()
	p.want(_Lbrack)
	x := new(IndexExpr)
	x.pos = pos
	x.X = typ
	if p.tok == _Rbrack {
		p.syntaxError("expecting type")
		x.Index = p.badExpr()
	} else {
		x.Index, _ = p.typeList()
	}
	p.want(_Rbrack)
	return x
}

func (p *parser) funcType(context string) ([]*Field, *FuncType) {
	if trace {
		defer p.trace("funcType")()
	}

	typ := new(FuncType)
	typ.pos = p.pos()

	var tparamList []*Field
	if p.allowGenerics() && p.got(_Lbrack) {
		if context != "" {
			// 接受但投诉
			p.syntaxErrorAt(typ.pos, context+" must have no type parameters")
		}
		if p.tok == _Rbrack {
			p.syntaxError("empty type parameter list")
			p.next()
		} else {
			tparamList = p.paramList(nil, nil, _Rbrack, true)
		}
	}

	p.want(_Lparen)
	typ.ParamList = p.paramList(nil, nil, _Rparen, false)
	typ.ResultList = p.funcResult()

	return tparamList, typ
}

// /“[”已经被消费，pos是它的位置。
// 如果len！=nil它是已消耗的数组长度。
func (p *parser) arrayType(pos Pos, len Expr) Expr {
	if trace {
		defer p.trace("arrayType")()
	}

	if len == nil && !p.got(_DotDotDot) {
		p.xnest++
		len = p.expr()
		p.xnest--
	}
	if p.tok == _Comma {
		// 在类型参数
		// 列表中接受尾随逗号，但在数组类型声明中不接受尾随逗号。
		// 接受更好的错误处理，但抱怨。
		p.syntaxError("unexpected comma; expecting ]")
		p.next()
	}
	p.want(_Rbrack)
	t := new(ArrayType)
	t.pos = pos
	t.Len = len
	t.Elem = p.type_()
	return t
}

// /“[”和“]”已经被消费，pos是“[”的位置。
func (p *parser) sliceType(pos Pos) Expr {
	t := new(SliceType)
	t.pos = pos
	t.Elem = p.type_()
	return t
}

func (p *parser) chanElem() Expr {
	if trace {
		defer p.trace("chanElem")()
	}

	typ := p.typeOrNil()
	if typ == nil {
		typ = p.badExpr()
		p.syntaxError("missing channel element type")
		// 假设元素类型根本不存在-不要推进
	}

	return typ
}

// /StructType=“struct”“{FieldDecl”；“}"}" . 
func (p *parser) structType() *StructType {
	if trace {
		defer p.trace("structType")()
	}

	typ := new(StructType)
	typ.pos = p.pos()

	p.want(_Struct)
	p.want(_Lbrace)
	p.list(_Semi, _Rbrace, func() bool {
		p.fieldDecl(typ)
		return false
	})

	return typ
}

// InterfaceType=“interface”“{（MethodDecl | EmbeddedElem | TypeList）；”}"}" . 
// TypeList=“type”type{”，“type}。
// TODO（gri）删除类型列表语法如果我们接受#45346 
func (p *parser) interfaceType() *InterfaceType {
	if trace {
		defer p.trace("interfaceType")()
	}

	typ := new(InterfaceType)
	typ.pos = p.pos()

	p.want(_Interface)
	p.want(_Lbrace)
	p.list(_Semi, _Rbrace, func() bool {
		switch p.tok {
		case _Name:
			f := p.methodDecl()
			if f.Name == nil && p.allowGenerics() {
				f = p.embeddedElem(f)
			}
			typ.MethodList = append(typ.MethodList, f)
			return false

		case _Lparen:
			// TODO（gri）需要决定如何调整此限制。
			p.syntaxError("cannot parenthesize embedded type")
			f := new(Field)
			f.pos = p.pos()
			p.next()
			f.Type = p.qualifiedName(nil)
			p.want(_Rparen)
			typ.MethodList = append(typ.MethodList, f)
			return false

		case _Operator:
			if p.op == Tilde && p.allowGenerics() {
				typ.MethodList = append(typ.MethodList, p.embeddedElem(nil))
				return false
			}

		default:
			if p.allowGenerics() {
				pos := p.pos()
				if t := p.typeOrNil(); t != nil {
					f := new(Field)
					f.pos = pos
					f.Type = t
					typ.MethodList = append(typ.MethodList, p.embeddedElem(f))
					return false
				}
			}
		}

		if p.allowGenerics() {
			p.syntaxError("expecting method or embedded element")
			p.advance(_Semi, _Rbrace)
			return false
		}

		p.syntaxError("expecting method or interface name")
		p.advance(_Semi, _Rbrace)
		return false
	})

	return typ
}

// 结果=参数|类型。
func (p *parser) funcResult() []*Field {
	if trace {
		defer p.trace("funcResult")()
	}

	if p.got(_Lparen) {
		return p.paramList(nil, nil, _Rparen, false)
	}

	pos := p.pos()
	if typ := p.typeOrNil(); typ != nil {
		f := new(Field)
		f.pos = pos
		f.Type = typ
		return []*Field{f}
	}

	return nil
}

func (p *parser) addField(styp *StructType, pos Pos, name *Name, typ Expr, tag *BasicLit) {
	if tag != nil {
		for i := len(styp.FieldList) - len(styp.TagList); i > 0; i-- {
			styp.TagList = append(styp.TagList, nil)
		}
		styp.TagList = append(styp.TagList, tag)
	}

	f := new(Field)
	f.pos = pos
	f.Name = name
	f.Type = typ
	styp.FieldList = append(styp.FieldList, f)

	if debug && tag != nil && len(styp.FieldList) != len(styp.TagList) {
		panic("inconsistent struct field list")
	}
}

// FieldDecl=（标识符列表类型|匿名字段）[Tag]。
// 匿名字段=[“*”]类型名。
// Tag=string_lit。
func (p *parser) fieldDecl(styp *StructType) {
	if trace {
		defer p.trace("fieldDecl")()
	}

	pos := p.pos()
	switch p.tok {
	case _Name:
		name := p.name()
		if p.tok == _Dot || p.tok == _Literal || p.tok == _Semi || p.tok == _Rbrace {
			// 嵌入式类型
			typ := p.qualifiedName(name)
			tag := p.oliteral()
			p.addField(styp, pos, nil, typ, tag)
			break
		}

		// 名称1，名称2。。。输入[tag]
		names := p.nameList(name)
		var typ Expr

		// 小心跳舞：我们不知道是否有嵌入式实例化的
		// 输入t[P1，P2，…]或数组/切片类型[P]E或[]E的字段T。
		if p.allowGenerics() && len(names) == 1 && p.tok == _Lbrack {
			typ = p.arrayOrTArgs()
			if typ, ok := typ.(*IndexExpr); ok {
				// 嵌入类型T[P1，P2，…]
				typ.X = name // name==names[0]
				tag := p.oliteral()
				p.addField(styp, pos, nil, typ, tag)
				break
			}
		} else {
			// T P 
			typ = p.type_()
		}

		tag := p.oliteral()

		for _, name := range names {
			p.addField(styp, name.Pos(), name, typ, tag)
		}

	case _Star:
		p.next()
		var typ Expr
		if p.tok == _Lparen {
			// *（T）
			p.syntaxError("cannot parenthesize embedded type")
			p.next()
			typ = p.qualifiedName(nil)
			p.got(_Rparen) // /如果缺少
		} else {
			// *T 
			typ = p.qualifiedName(nil)
		}
		tag := p.oliteral()
		p.addField(styp, pos, nil, newIndirect(pos, typ), tag)

	case _Lparen:
		p.syntaxError("cannot parenthesize embedded type")
		p.next()
		var typ Expr
		if p.tok == _Star {
			// （*T）
			pos := p.pos()
			p.next()
			typ = newIndirect(pos, p.qualifiedName(nil))
		} else {
			// （T）
			typ = p.qualifiedName(nil)
		}
		p.got(_Rparen) // /如果缺少
		tag := p.oliteral()
		p.addField(styp, pos, nil, typ, tag)

	default:
		p.syntaxError("expecting field name or embedded type")
		p.advance(_Semi, _Rbrace)
	}
}

func (p *parser) arrayOrTArgs() Expr {
	if trace {
		defer p.trace("arrayOrTArgs")()
	}

	pos := p.pos()
	p.want(_Lbrack)
	if p.got(_Rbrack) {
		return p.sliceType(pos)
	}

	// x[n]E或x[n，]，x[n1，n2]。。。
	n, comma := p.typeList()
	p.want(_Rbrack)
	if !comma {
		if elem := p.typeOrNil(); elem != nil {
			// x[n]E 
			t := new(ArrayType)
			t.pos = pos
			t.Len = n
			t.Elem = elem
			return t
		}
	}

	// x[n，]，x[n1，n2]。。。
	t := new(IndexExpr)
	t.pos = pos
	// t.X将由调用方填写
	t.Index = n
	return t
}

func (p *parser) oliteral() *BasicLit {
	if p.tok == _Literal {
		b := new(BasicLit)
		b.pos = p.pos()
		b.Value = p.lit
		b.Kind = p.kind
		b.Bad = p.bad
		p.next()
		return b
	}
	return nil
}

// MethodSpec=MethodName签名| InterfaceTypeName。
// MethodName=标识符。
// InterfaceTypeName=TypeName。
func (p *parser) methodDecl() *Field {
	if trace {
		defer p.trace("methodDecl")()
	}

	f := new(Field)
	f.pos = p.pos()
	name := p.name()

	// 接受潜在名单，但抱怨
	// TODO（gri）我们可能不再需要这个特殊检查了。
	// 没有人写这种代码。这是从古代
	// 开始。
	hasNameList := false
	for p.got(_Comma) {
		p.name()
		hasNameList = true
	}
	if hasNameList {
		p.syntaxError("name list not allowed in interface type")
		// 已经取得了进展，无需进一步改进
	}

	const context = "interface method"

	switch p.tok {
	case _Lparen:
		// 方法
		f.Name = name
		_, f.Type = p.funcType(context)

	case _Lbrack:
		if p.allowGenerics() {
			// 小心跳舞：我们不知道我们是否有一个通用方法m[tc]（x t）
			// 或一个嵌入的实例化类型t[P1，P2]（为了解析的通用性和健壮性，我们接受通用方法
			// 方法）。
			pos := p.pos()
			p.next()

			// 不允许使用空类型参数或参数列表。
			// 将[]视为缺席。
			if p.tok == _Rbrack {
				// name[]
				pos := p.pos()
				p.next()
				if p.tok == _Lparen {
					// name[]（
					p.errorAt(pos, "empty type parameter list")
					f.Name = name
					_, f.Type = p.funcType(context)
				} else {
					p.errorAt(pos, "empty type argument list")
					f.Type = name
				}
				break
			}

			// 类型参数列表看起来像只有
			// 类型的参数列表。解析参数列表，然后再决定。
			list := p.paramList(nil, nil, _Rbrack, false)
			if len(list) == 0 {
				// 类型参数列表不是[]，但由于其他错误（由paramList报告），我们没有得到任何
				// 。对待
				// 就好像[]不存在一样。
				if p.tok == _Lparen {
					f.Name = name
					_, f.Type = p.funcType(context)
				} else {
					f.Type = name
				}
				break
			}

			// len（list）>0 
			if list[0].Name != nil {
				// 泛型方法
				f.Name = name
				_, f.Type = p.funcType(context)
				// TODO（gri）记录列表作为类型参数列表，带有f。键入
				// 如果我们想键入，请检查泛型方法。
				// 现在，报告一个错误，这样这就不是一个静默事件。
				p.errorAt(pos, "interface method must have no type parameters")
				break
			}

			// embedded实例化类型
			t := new(IndexExpr)
			t.pos = pos
			t.X = name
			if len(list) == 1 {
				t.Index = list[0].Type
			} else {
				// len（列表）>1 
				l := new(ListExpr)
				l.pos = list[0].Pos()
				l.ElemList = make([]Expr, len(list))
				for i := range list {
					l.ElemList[i] = list[i].Type
				}
				t.Index = l
			}
			f.Type = t
			break
		}
		fallthrough

	default:
		// embedded类型
		f.Type = p.qualifiedName(name)
	}

	return f
}

// EmbeddedElem=MethodSpec | EmbeddedTerm{“|”EmbeddedTerm}。
func (p *parser) embeddedElem(f *Field) *Field {
	if trace {
		defer p.trace("embeddedElem")()
	}

	if f == nil {
		f = new(Field)
		f.pos = p.pos()
		f.Type = p.embeddedTerm()
	}

	for p.tok == _Operator && p.op == Or {
		t := new(Operation)
		t.pos = p.pos()
		t.Op = Or
		p.next()
		t.X = f.Type
		t.Y = p.embeddedTerm()
		f.Type = t
	}

	return f
}

// EmbeddedTerm=[“~”]类型。
func (p *parser) embeddedTerm() Expr {
	if trace {
		defer p.trace("embeddedTerm")()
	}

	if p.tok == _Operator && p.op == Tilde {
		t := new(Operation)
		t.pos = p.pos()
		t.Op = Tilde
		p.next()
		t.X = p.type_()
		return t
	}

	t := p.typeOrNil()
	if t == nil {
		t = p.badExpr()
		p.syntaxError("expecting ~ term or type")
		p.advance(_Operator, _Semi, _Rparen, _Rbrack, _Rbrace)
	}

	return t
}

// 参数decl=[IdentifierList][“…”]类型
func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
	if trace {
		defer p.trace("paramDeclOrNil")()
	}

	// 类型参数列表中的类型集表示法是ok的
	typeSetsOk := follow == _Rbrack

	pos := p.pos()
	if name != nil {
		pos = name.pos
	} else if typeSetsOk && p.tok == _Operator && p.op == Tilde {
		// /“~”。。。姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名姓名。。。
		return p.embeddedElem(nil)
	}

	f := new(Field)
	f.pos = pos

	if p.tok == _Name || name != nil {
		if name == nil {
			name = p.name()
		}

		if p.allowGenerics() && p.tok == _Lbrack {
			f.Type = p.arrayOrTArgs()
			if typ, ok := f.Type.(*IndexExpr); ok {
				typ.X = name
			} else {
				f.Name = name
			}
			if typeSetsOk && p.tok == _Operator && p.op == Or {
				// 名称“[“n”]“E”|”。。。
				f = p.embeddedElem(f)
			}
			return f
		}

		if p.tok == _Dot {
			// 名称“。。。
			f.Type = p.qualifiedName(name)
			if typeSetsOk && p.tok == _Operator && p.op == Or {
				// 名称”名称“|”。。。
				f = p.embeddedElem(f)
			}
			return f
		}

		if typeSetsOk && p.tok == _Operator && p.op == Or {
			// 名称“|”。。。
			f.Type = name
			return p.embeddedElem(f)
		}

		f.Name = name
	}

	if p.tok == _DotDotDot {
		// /[姓名]“。。。
		t := new(DotsType)
		t.pos = p.pos()
		p.next()
		t.Elem = p.typeOrNil()
		if t.Elem == nil {
			t.Elem = p.badExpr()
			p.syntaxError("... is missing type")
		}
		f.Type = t
		return f
	}

	if typeSetsOk && p.tok == _Operator && p.op == Tilde {
		// /[姓名]“~”。。。
		f.Type = p.embeddedElem(nil).Type
		return f
	}

	f.Type = p.typeOrNil()
	if typeSetsOk && p.tok == _Operator && p.op == Or && f.Type != nil {
		// /[name]键入“|”
		f = p.embeddedElem(f)
	}
	if f.Name != nil || f.Type != nil {
		return f
	}

	p.syntaxError("expecting " + tokstring(follow))
	p.advance(_Comma, follow)
	return nil
}

// Parameters=“（“[ParameterList[”，“]）”。
// ParameterList=ParameterDecl{”，“ParameterDecl}。
// /”（“或”[”已被消费。
// 如果name！=nil，它是“（”或“[”）之后的第一个名字。
// 如果typ！=nil，name必须是！=nil，和（name，typ）是列表中的第一个字段。
// 在结果列表中，要么所有字段都有名称，要么没有字段有名称。
func (p *parser) paramList(name *Name, typ Expr, close token, requireNames bool) (list []*Field) {
	if trace {
		defer p.trace("paramList")()
	}

	// 如果我们在
	// 参数列表的末尾，p.list将不会调用其函数参数。如果我们有一个完整的字段，在这里处理这个案例。
	if name != nil && typ != nil && p.tok == close {
		p.next()
		par := new(Field)
		par.pos = name.pos
		par.Name = name
		par.Type = typ
		return []*Field{par}
	}

	var named int // 具有显式名称和类型的参数数量
	var typed int // 具有显式类型的参数数量
	end := p.list(_Comma, close, func() bool {
		var par *Field
		if typ != nil {
			if debug && name == nil {
				panic("initial type provided without name")
			}
			par = new(Field)
			par.pos = name.pos
			par.Name = name
			par.Type = typ
		} else {
			par = p.paramDeclOrNil(name, close)
		}
		name = nil // 如果存在
		if par != nil {
			if debug && par.Name == nil && par.Type == nil {
				panic("parameter without name or type")
			}
			if par.Name != nil && par.Type != nil {
				named++
			}
			if par.Type != nil {
				typed++
			}
			list = append(list, par)
		}
		return false
	})

	if len(list) == 0 {
		return
	}

	if named == 0 && !requireNames {
		for _, par := range list {
			if typ := par.Name; typ != nil {
				par.Type = typ
				par.Name = nil
			}
		}
	} else if named != len(list) {
		for i := len(list) - 1; i >= 0; i-- {
			par := list[i]
			if par.Type != nil {
				typ = par.Type
				if par.Name == nil {
					pos = StartPos(typ)
					par.Name = NewName(pos, "_")
				}
			} else if typ != nil {
				par.Type = typ
			} else {
				pos = par.Name.Pos()
				t := p.badExpr()
				t.pos = pos // 正确的位置
				par.Type = t
			}
		}
		if pos.IsKnown() {
			var msg string
			if requireNames {
				if named == typed {
					pos = end // 关闭时的位置错误]
					msg = "missing type constraint"
				} else {
					msg = "type parameters must be named"
				}
			} else {
				msg = "mixed named and unnamed parameters"
			}
			p.syntaxErrorAt(pos, msg)
		}
	}

	return
}

func (p *parser) badExpr() *BadExpr {
	b := new(BadExpr)
	b.pos = p.pos()
	return b
}

// /------------------------------------------------------------------------------------------------------------------
// 语句

// SimpleStmt=EmptySMTT |表达式TMT |发送stmt incdecsmt |赋值| ShortVarDecl。
func (p *parser) simpleStmt(lhs Expr, keyword token) SimpleStmt {
	if trace {
		defer p.trace("simpleStmt")()
	}

	if keyword == _For && p.tok == _Range {
		// lhs++或lhs--
		if debug && lhs != nil {
			panic("invalid call of simpleStmt")
		}
		return p.newRangeClause(nil, false)
	}

	if lhs == nil {
		lhs = p.exprList()
	}

	if _, ok := lhs.(*ListExpr); !ok && p.tok != _Assign && p.tok != _Define {
		pos := p.pos()
		switch p.tok {
		case _AssignOp:
			// lhs++或lhs-
			op := p.op
			p.next()
			return p.newAssignStmt(pos, op, lhs, p.expr())

		case _IncOp:
			op := p.op
			p.next()
			return p.newAssignStmt(pos, op, lhs, nil)

		case _Arrow:
			// lhs<-rhs-
			s := new(SendStmt)
			s.pos = pos
			p.next()
			s.Chan = lhs
			s.Value = p.expr()
			return s

		default:
			// expr-
			// expr-
			s := new(ExprStmt)
			s.pos = lhs.Pos()
			s.X = lhs
			return s
		}
	}

	// expr\U list 
	switch p.tok {
	case _Assign, _Define:
		pos := p.pos()
		var op Operator
		if p.tok == _Define {
			op = Def
		}
		p.next()

		if keyword == _For && p.tok == _Range {
			// expr\U list op=\U Range expr-
			return p.newRangeClause(lhs, op == Def)
		}

		rhs := p.exprList()

		if x, ok := rhs.(*TypeSwitchGuard); ok && keyword == _Switch && op == Def {
			if lhs, ok := lhs.(*Name); ok {
				x.Lhs = lhs
				s := new(ExprStmt)
				s.pos = x.Pos()
				s.X = x
				return s
			}
		}

		return p.newAssignStmt(pos, op, lhs, rhs)

	default:
		p.syntaxError("expecting := or = or comma")
		p.advance(_Semi, _Rbrace)
		// 充分利用我们现有的
		if x, ok := lhs.(*ListExpr); ok {
			lhs = x.ElemList[0]
		}
		s := new(ExprStmt)
		s.pos = lhs.Pos()
		s.X = lhs
		return s
	}
}

func (p *parser) newRangeClause(lhs Expr, def bool) *RangeClause {
	r := new(RangeClause)
	r.pos = p.pos()
	p.next() // 消费范围
	r.Lhs = lhs
	r.Def = def
	r.X = p.expr()
	return r
}

func (p *parser) newAssignStmt(pos Pos, op Operator, lhs, rhs Expr) *AssignStmt {
	a := new(AssignStmt)
	a.pos = pos
	a.Op = op
	a.Lhs = lhs
	a.Rhs = rhs
	return a
}

func (p *parser) labeledStmtOrNil(label *Name) Stmt {
	if trace {
		defer p.trace("labeledStmt")()
	}

	s := new(LabeledStmt)
	s.pos = p.pos()
	s.Label = label

	p.want(_Colon)

	if p.tok == _Rbrace {
		// 我们需要一个语句（包括一个空语句），它必须是
		// 以分号结尾。因为分号可以在
		// an _Rbrace，看到一个_Rbrace意味着一个空语句。
		e := new(EmptyStmt)
		e.pos = p.pos()
		s.Stmt = e
		return s
	}

	s.Stmt = p.stmtOrNil()
	if s.Stmt != nil {
		return s
	}

	// 在“：”标记行报告错误
	p.syntaxErrorAt(s.pos, "missing statement after label")
	// 我们已经在标记语句的末尾了-无需提前
	return nil // 避免后续错误（请参见fixedbug/bug274.go）
}

// 除非我们知道p.tok=\u Lbrace，否则上下文必须是非空字符串。
func (p *parser) blockStmt(context string) *BlockStmt {
	if trace {
		defer p.trace("blockStmt")()
	}

	s := new(BlockStmt)
	s.pos = p.pos()

	// 来自C的人可能忘记了在Go 
	if !p.got(_Lbrace) {
		p.syntaxError("expecting { after " + context)
		p.advance(_Name, _Rbrace)
		s.Rbrace = p.pos() // 如果我们发现“}”
		if p.got(_Rbrace) {
			return s
		}
	}

	s.List = p.stmtList()
	s.Rbrace = p.pos()
	p.want(_Rbrace)

	return s
}

func (p *parser) declStmt(f func(*Group) Decl) *DeclStmt {
	if trace {
		defer p.trace("declStmt")()
	}

	s := new(DeclStmt)
	s.pos = p.pos()

	p.next() // /\u Const、\u Type或_var
	s.DeclList = p.appendGroup(nil, f)

	return s
}

func (p *parser) forStmt() Stmt {
	if trace {
		defer p.trace("forStmt")()
	}

	s := new(ForStmt)
	s.pos = p.pos()

	s.Init, s.Cond, s.Post = p.header(_For)
	s.Body = p.blockStmt("for clause")

	return s
}

func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleStmt) {
	p.want(keyword)

	if p.tok == _Lbrace {
		if keyword == _If {
			p.syntaxError("missing condition in if statement")
			cond = p.badExpr()
		}
		return
	}
	// p.tok！=_Lbrace 

	outer := p.xnest
	p.xnest = -1

	if p.tok != _Semi {
		// 接受潜在的varDecl，但抱怨
		if p.got(_Var) {
			p.syntaxError(fmt.Sprintf("var declaration not allowed in %s initializer", tokstring(keyword)))
		}
		init = p.simpleStmt(nil, keyword)
		// 如果我们有一个range子句，我们就完成了（只能发生在关键字==\u for）。
		if _, ok := init.(*RangeClause); ok {
			p.xnest = outer
			return
		}
	}

	var condStmt SimpleStmt
	var semi struct {
		pos Pos
		lit string // 如果pos.IsKnown（）
	}
	if p.tok != _Lbrace {
		if p.tok == _Semi {
			semi.pos = p.pos()
			semi.lit = p.lit
			p.next()
		} else {
			// 请求一个“{”而不是“；”，则有效。为了更好地同步，这里会出现一条更好的错误消息
			p.want(_Lbrace)
			if p.tok != _Lbrace {
				p.advance(_Lbrace, _Rbrace) // 例如，问题#22581）
			}
		}
		if keyword == _For {
			if p.tok != _Semi {
				if p.tok == _Lbrace {
					p.syntaxError("expecting for loop condition")
					goto done
				}
				condStmt = p.simpleStmt(nil, 0 /* range not permitted */)
			}
			p.want(_Semi)
			if p.tok != _Lbrace {
				post = p.simpleStmt(nil, 0 /* range not permitted */)
				if a, _ := post.(*AssignStmt); a != nil && a.Op == Def {
					p.syntaxErrorAt(a.Pos(), "cannot declare in post statement of for loop")
				}
			}
		} else if p.tok != _Lbrace {
			condStmt = p.simpleStmt(nil, keyword)
		}
	} else {
		condStmt = init
		init = nil
	}

done:
	// unpack condsmt 
	switch s := condStmt.(type) {
	case nil:
		if keyword == _If && semi.pos.IsKnown() {
			if semi.lit != "semicolon" {
				p.syntaxErrorAt(semi.pos, fmt.Sprintf("unexpected %s, expecting { after if clause", semi.lit))
			} else {
				p.syntaxErrorAt(semi.pos, "missing condition in if statement")
			}
			b := new(BadExpr)
			b.pos = semi.pos
			cond = b
		}
	case *ExprStmt:
		cond = s.X
	default:
		// 一个常见的语法错误是写“=”而不是“=”，
		// 这会将表达式转换为赋值。在这种情况下，请提供更明确的错误消息，以防止进一步混淆。
		var str string
		if as, ok := s.(*AssignStmt); ok && as.Op == 0 {
			// 用括号强调赋值的左和右，突出显示“=”。始终这样做——不值得费心去做。只为“复杂”的左右两边。
			str = "assignment (" + String(as.Lhs) + ") = (" + String(as.Rhs) + ")"
		} else {
			str = String(s)
		}
		p.syntaxErrorAt(s.Pos(), fmt.Sprintf("cannot use %s as value", str))
	}

	p.xnest = outer
	return
}

func (p *parser) ifStmt() *IfStmt {
	if trace {
		defer p.trace("ifStmt")()
	}

	s := new(IfStmt)
	s.pos = p.pos()

	s.Init, s.Cond, _ = p.header(_If)
	s.Then = p.blockStmt("if clause")

	if p.got(_Else) {
		switch p.tok {
		case _If:
			s.Else = p.ifStmt()
		case _Lbrace:
			s.Else = p.blockStmt("")
		default:
			p.syntaxError("else must be followed by if or statement block")
			p.advance(_Name, _Rbrace)
		}
	}

	return s
}

func (p *parser) switchStmt() *SwitchStmt {
	if trace {
		defer p.trace("switchStmt")()
	}

	s := new(SwitchStmt)
	s.pos = p.pos()

	s.Init, s.Tag, _ = p.header(_Switch)

	if !p.got(_Lbrace) {
		p.syntaxError("missing { after switch clause")
		p.advance(_Case, _Default, _Rbrace)
	}
	for p.tok != _EOF && p.tok != _Rbrace {
		s.Body = append(s.Body, p.caseClause())
	}
	s.Rbrace = p.pos()
	p.want(_Rbrace)

	return s
}

func (p *parser) selectStmt() *SelectStmt {
	if trace {
		defer p.trace("selectStmt")()
	}

	s := new(SelectStmt)
	s.pos = p.pos()

	p.want(_Select)
	if !p.got(_Lbrace) {
		p.syntaxError("missing { after select clause")
		p.advance(_Case, _Default, _Rbrace)
	}
	for p.tok != _EOF && p.tok != _Rbrace {
		s.Body = append(s.Body, p.commClause())
	}
	s.Rbrace = p.pos()
	p.want(_Rbrace)

	return s
}

func (p *parser) caseClause() *CaseClause {
	if trace {
		defer p.trace("caseClause")()
	}

	c := new(CaseClause)
	c.pos = p.pos()

	switch p.tok {
	case _Case:
		p.next()
		c.Cases = p.exprList()

	case _Default:
		p.next()

	default:
		p.syntaxError("expecting case or default or }")
		p.advance(_Colon, _Case, _Default, _Rbrace)
	}

	c.Colon = p.pos()
	p.want(_Colon)
	c.Body = p.stmtList()

	return c
}

func (p *parser) commClause() *CommClause {
	if trace {
		defer p.trace("commClause")()
	}

	c := new(CommClause)
	c.pos = p.pos()

	switch p.tok {
	case _Case:
		p.next()
		c.Comm = p.simpleStmt(nil, 0)

		// 语法将这里可能的简单语句限制为：
		// 
		// lhs<-x（发送语句）
		// <-x 
		// lhs=<-x 
		// lhs:=<-x 
		// 
		// 所有这些（以及更多）都被simpleStmt和无效的
		// TODO（gri）最终可能想要限制有效的语法树
		// 。

	case _Default:
		p.next()

	default:
		p.syntaxError("expecting case or default or }")
		p.advance(_Colon, _Case, _Default, _Rbrace)
	}

	c.Colon = p.pos()
	p.want(_Colon)
	c.Body = p.stmtList()

	return c
}

// Statement=
// Declaration | labeledsmt | SimpleStmt | 
// GoStmt | ReturnStmt | BreakStmt | ContinueStmt GotoStmt | 
// fallthroughthhstmt | Block | IfStmt SwitchStmt。
func (p *parser) stmtOrNil() Stmt {
	if trace {
		defer p.trace("stmt " + p.tok.String())()
	}

	// 大多数语句（赋值）以标识符开头；
	// 在做任何更昂贵的事情之前，先找一下。
	if p.tok == _Name {
		p.clearPragma()
		lhs := p.exprList()
		if label, ok := lhs.(*Name); ok && p.tok == _Colon {
			return p.labeledStmtOrNil(label)
		}
		return p.simpleStmt(lhs, 0)
	}

	switch p.tok {
	case _Var:
		return p.declStmt(p.varDecl)

	case _Const:
		return p.declStmt(p.constDecl)

	case _Type:
		return p.declStmt(p.typeDecl)
	}

	p.clearPragma()

	switch p.tok {
	case _Lbrace:
		return p.blockStmt("")

	case _Operator, _Star:
		switch p.op {
		case Add, Sub, Mul, And, Xor, Not:
			return p.simpleStmt(nil, 0) // 一元运算符
		}

	case _Literal, _Func, _Lparen, // 操作数
		_Lbrack, _Struct, _Map, _Chan, _Interface, // 复合类型
		_Arrow: // 接收运算符
		return p.simpleStmt(nil, 0)

	case _For:
		return p.forStmt()

	case _Switch:
		return p.switchStmt()

	case _Select:
		return p.selectStmt()

	case _If:
		return p.ifStmt()

	case _Fallthrough:
		s := new(BranchStmt)
		s.pos = p.pos()
		p.next()
		s.Tok = _Fallthrough
		return s

	case _Break, _Continue:
		s := new(BranchStmt)
		s.pos = p.pos()
		s.Tok = p.tok
		p.next()
		if p.tok == _Name {
			s.Label = p.name()
		}
		return s

	case _Go, _Defer:
		return p.callStmt()

	case _Goto:
		s := new(BranchStmt)
		s.pos = p.pos()
		s.Tok = _Goto
		p.next()
		s.Label = p.name()
		return s

	case _Return:
		s := new(ReturnStmt)
		s.pos = p.pos()
		p.next()
		if p.tok != _Semi && p.tok != _Rbrace {
			s.Results = p.exprList()
		}
		return s

	case _Semi:
		s := new(EmptyStmt)
		s.pos = p.pos()
		return s
	}

	return nil
}

// 语句列表={Statement]；“}。
func (p *parser) stmtList() (l []Stmt) {
	if trace {
		defer p.trace("stmtList")()
	}

	for p.tok != _EOF && p.tok != _Rbrace && p.tok != _Case && p.tok != _Default {
		s := p.stmtOrNil()
		p.clearPragma()
		if s == nil {
			break
		}
		l = append(l, s)
		// /“；”在“}”之前是可选的
		if !p.got(_Semi) && p.tok != _Rbrace {
			p.syntaxError("at end of statement")
			p.advance(_Semi, _Rbrace, _Case, _Default)
			p.got(_Semi) // 避免虚假的空语句
		}
	}
	return
}

// argList解析一个可能是空的、以逗号分隔的参数列表，
// 可选后跟逗号（如果不是空的），并以“）”结尾。
// 最后一个参数后面可能跟“…”。
// 
// argList=[arg{”，“arg}[“…]”[ "," ] ] ")" . 
func (p *parser) argList() (list []Expr, hasDots bool) {
	if trace {
		defer p.trace("argList")()
	}

	p.xnest++
	p.list(_Comma, _Rparen, func() bool {
		list = append(list, p.expr())
		hasDots = p.got(_DotDotDot)
		return hasDots
	})
	p.xnest--

	return
}

// ----------------------------------------------------------------------------------------
// 常见产品

func (p *parser) name() *Name {
	// 无需跟踪以避免过于详细的输出

	if p.tok == _Name {
		n := NewName(p.pos(), p.lit)
		p.next()
		return n
	}

	n := NewName(p.pos(), "_")
	p.syntaxError("expecting name")
	p.advance()
	return n
}

// 标识列表=标识符{”，“标识符}。
// 必须提供名字。
func (p *parser) nameList(first *Name) []*Name {
	if trace {
		defer p.trace("nameList")()
	}

	if debug && first == nil {
		panic("first name not provided")
	}

	l := []*Name{first}
	for p.got(_Comma) {
		l = append(l, p.name())
	}

	return l
}

// 可以提供名字，也可以不提供。
func (p *parser) qualifiedName(name *Name) Expr {
	if trace {
		defer p.trace("qualifiedName")()
	}

	var x Expr
	switch {
	case name != nil:
		x = name
	case p.tok == _Name:
		x = p.name()
	default:
		x = NewName(p.pos(), "_")
		p.syntaxError("expecting name")
		p.advance(_Dot, _Semi, _Rbrace)
	}

	if p.tok == _Dot {
		s := new(SelectorExpr)
		s.pos = p.pos()
		p.next()
		s.X = x
		s.Sel = p.name()
		x = s
	}

	if p.allowGenerics() && p.tok == _Lbrack {
		x = p.typeInstance(x)
	}

	return x
}

// ExpressionList=表达式{”，“表达式}。
func (p *parser) exprList() Expr {
	if trace {
		defer p.trace("exprList")()
	}

	x := p.expr()
	if p.got(_Comma) {
		list := []Expr{x, p.expr()}
		for p.got(_Comma) {
			list = append(list, p.expr())
		}
		t := new(ListExpr)
		t.pos = x.Pos()
		t.ElemList = list
		x = t
	}
	return x
}

// typeList解析一个非空的、以逗号分隔的表达式列表，
// 后面可以加逗号。第一个列表元素可以是任何
// 表达式，所有其他列表元素必须是类型表达式。
// 如果有多个参数，则结果为*ListExpr。
// 逗号结果指示是否存在（分隔或
// 尾随）逗号。
// 
// typeList=arg{，“arg}[”，“]。
func (p *parser) typeList() (x Expr, comma bool) {
	if trace {
		defer p.trace("typeList")()
	}

	p.xnest++
	x = p.expr()
	if p.got(_Comma) {
		comma = true
		if t := p.typeOrNil(); t != nil {
			list := []Expr{x, t}
			for p.got(_Comma) {
				if t = p.typeOrNil(); t == nil {
					break
				}
				list = append(list, t)
			}
			l := new(ListExpr)
			l.pos = x.Pos() // /==列表[0]。Pos（）
			l.ElemList = list
			x = l
		}
	}
	p.xnest--
	return
}

// unparen删除表达式周围的所有括号。
func unparen(x Expr) Expr {
	for {
		p, ok := x.(*ParenExpr)
		if !ok {
			break
		}
		x = p.X
	}
	return x
}
